package com.artezio.testapp.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.artezio.testapp.domain.City;
import com.artezio.testapp.domain.ajax.DataTablesParamModel;

@Repository
public class CityDAOImpl implements CityDAO {

	@SuppressWarnings("unused")
	private static final Logger logger = LoggerFactory
			.getLogger(CityDAOImpl.class);

	@Autowired
	private SessionFactory sessionFactory;

	public void addCity(City city) {
		sessionFactory.getCurrentSession().saveOrUpdate(city);
	}

	public City getCity(Integer id) {

		return (City)sessionFactory.getCurrentSession()
				.createCriteria(City.class).add(Restrictions.idEq(id))
				.setFetchMode("persons", FetchMode.JOIN).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<City> listCity() {

		return sessionFactory.getCurrentSession().createCriteria(City.class)
				.list();
	}

	public void removeCity(Integer id) {
		City city = (City) sessionFactory.getCurrentSession().load(City.class,
				id);
		if (null != city) {
			sessionFactory.getCurrentSession().delete(city);
		}

	}

	public int getCount() {
		return (Integer) sessionFactory.getCurrentSession()
				.createCriteria(City.class)
				.setProjection(Projections.count("id")).uniqueResult();
	}
	
	public int getFilteredCount(String filterString) {
		return (Integer) sessionFactory.getCurrentSession()
				.createCriteria(City.class)
				.add(Restrictions.like("name", filterString, MatchMode.ANYWHERE))
				.setProjection(Projections.count("id")).uniqueResult();
	}
	
	@SuppressWarnings("unchecked")
	public List<City> listCity(DataTablesParamModel param) {
		
		Criteria criteria = sessionFactory
				.getCurrentSession()
				.createCriteria(City.class);
		String orderingField = "id";
		
		// filtering
		if (param.sSearch != null && param.sSearch.length() > 0) {
			criteria = criteria.add(Restrictions.like("name",
					param.sSearch, MatchMode.ANYWHERE));
		}
		
		// ordering
		switch (param.iSortColumnIndex) {
		case 0:
			orderingField = "id";
			break;
		case 1:
			orderingField = "name";
			break;
		case 2:
			orderingField = "population";
			break;
		}
		
		Order order = (param.sSortDirection.equals("asc")) ? Order
				.asc(orderingField) : Order.desc(orderingField);
		criteria = criteria.addOrder(order);
		
		//pagination
		criteria = criteria.setFirstResult(param.iDisplayStart);
		criteria = criteria.setMaxResults(param.iDisplayLength);
		
		return criteria.list();
	}

}